package com.chaber.containers.presenters;

import java.text.DateFormat;
import java.text.ParseException;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TreeItem;
import javafx.scene.input.MouseEvent;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.util.StringUtils;

import com.chaber.containers.beans.ProductCategoryData;
import com.chaber.containers.common.ConstraintViolationEvent;
import com.chaber.containers.services.ProductCategoryService;
import com.chaber.containers.views.ProdCatAddModRemView;
import com.chaber.containers.views.ProdCatListView;

public class ProdCatAddModRemPresenter extends AbstractPresenter implements ApplicationListener<ConstraintViolationEvent<ProductCategoryData>> {

	@Autowired
	private ProdCatAddModRemView categoryAddModView;

	@Autowired
	private ProdCatListView prodCatListView;

	@Autowired
	private ProductCategoryService productCategoryService;
	
	@Autowired 
	private ProdCatListPresenter prodCatListPresenter;

	@Override
	public void bindViewActions() {
		this.prodCatListView.getProdCategoriesTree().setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent mouseEvt) {
				if (mouseEvt.getClickCount() == 1) {
					int selectedIndex = prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedIndex();

					if (selectedIndex > -1) {
						prodCatListView.activateActionButtons();
						
						//we cannot remove root category, which is not an an entity
						if (selectedIndex == 0) {
							prodCatListView.getRemoveButton().setDisable(true);
						}
					} else {
						prodCatListView.deactivateActionButtons();
					}

				} else if (mouseEvt.getClickCount() == 2 
						&& prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem() != null
						&& prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem().getParent() != null
						&& prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem().getValue() != null) {
					
					TreeItem<ProductCategoryData> selectedCatData = prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem();
					
					readProductCategoryDetails(selectedCatData.getValue().getId());
				}
			}
		});
		
		this.prodCatListView.getAddButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				initAddProductCategory();
			}
		});

		this.categoryAddModView.getSaveButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				saveProductCategory();
			}
		});

		this.categoryAddModView.getInitModifyButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				categoryAddModView.activateEdition();
				categoryAddModView.getCodeField().setDisable(true);
			}
		});

		this.categoryAddModView.getRemoveButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				removeProductCategory();
			}
		});

		this.prodCatListView.getRemoveButton().setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				removeProductCategory();
			}
		});
	}

	@Override
	public void onApplicationEvent(ConstraintViolationEvent<ProductCategoryData> event) {
		this.prepareValidationErrors(event, this.categoryAddModView.getErrorsBox());
	}
	
	private void initAddProductCategory() {
		this.categoryAddModView.clearFields();
		
		TreeItem<ProductCategoryData> selectedParentCat = prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem();
		if (selectedParentCat != null && selectedParentCat.getParent() != null && selectedParentCat.getValue() != null) {
			ProductCategoryData pCat = selectedParentCat.getValue();
			this.categoryAddModView.getParentCatField().setText(pCat.getFullName());
		} else {
			this.categoryAddModView.getParentCatField().setText(null);
		}
		
		this.categoryAddModView.activateEdition();
		this.categoryAddModView.show();
	}
	
	private void readProductCategoryDetails(Integer id) {
		this.categoryAddModView.clearFields();

		ProductCategoryData pCatData = this.productCategoryService.getProductCategory(id);
		this.populateProductCatDataToTheView(pCatData);

		this.categoryAddModView.getProductsTable().getItems().addAll(pCatData.getProducts());
		
		this.categoryAddModView.deactivateEdition();
		this.categoryAddModView.show();
	}

	private void saveProductCategory() {
		ProductCategoryData productCatToSave = this.populateProductCatDataFromView();
		this.productCategoryService.save(productCatToSave);
		
		this.prodCatListPresenter.buildTreeView();
		this.readProductCategoryDetails(productCatToSave.getId());
	}

	private void removeProductCategory() {
		TreeItem<ProductCategoryData> itemToRemove = prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem();
		if (itemToRemove != null && itemToRemove.getValue() != null && itemToRemove.getValue().getId() != null) {

			this.productCategoryService.remove(itemToRemove.getValue().getId());
			this.categoryAddModView.close();
			
			this.prodCatListPresenter.buildTreeView();
		}
	}

	private ProductCategoryData populateProductCatDataFromView() {
		ProductCategoryData productCatData = applicationContext.getBean(ProductCategoryData.class);

		productCatData.setCode(this.categoryAddModView.getCodeField().getText());
		productCatData.setName(this.categoryAddModView.getNameField().getText());

		DateFormat df = DateFormat.getDateInstance();
		if (!StringUtils.isEmpty(this.categoryAddModView.getCdField().getText())) {
			try {
				productCatData.setCreationDate(df.parse(this.categoryAddModView.getCdField().getText()));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		if (!StringUtils.isEmpty(this.categoryAddModView.getMdField().getText())) {
			try {
				productCatData.setModificationDate(df.parse(this.categoryAddModView.getMdField().getText()));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
		TreeItem<ProductCategoryData> selectedParentCat = this.prodCatListView.getProdCategoriesTree().getSelectionModel().getSelectedItem();
		if (selectedParentCat != null && selectedParentCat.getParent() != null && selectedParentCat.getValue() != null) {
			productCatData.setParentCategory(selectedParentCat.getValue());
		} 

		return productCatData;
	}

	private void populateProductCatDataToTheView(ProductCategoryData pCatData) {
		this.categoryAddModView.getCodeField().setText(pCatData.getCode());
		this.categoryAddModView.getNameField().setText(pCatData.getName());
		this.categoryAddModView.getCdField().setText(pCatData.getCreationDate() != null ? pCatData.getCreationDate().toString() : null);
		this.categoryAddModView.getMdField().setText(pCatData.getModificationDate() != null ? pCatData.getModificationDate().toString() : null);
		
		if (pCatData.getParentCategory() != null) {
			this.categoryAddModView.getParentCatField().setText(pCatData.getParentCategory().getFullName());
		} else {
			this.categoryAddModView.getParentCatField().setText(null);
		}
	}
}
